﻿using System;
using System.Xml;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Diagnostics;
using System.Windows.Forms;
using System.Collections;
using StockTrader.DAL.HoseAdapter.FileParser;
using StockTrader.DAL.HoseAdapter.Lib.Threading;
using StockTrader.DAL.HoseAdapter.BusinessLogic;
using StockTrader.DAL.HoseAdapter.FileParser.Structure;
using StockTrader.DAL.HoseAdapter.Lib;
using StockTrader.DAL.HoseAdapter.DataAccess;
using System.Configuration;
using System.IO;
using StockTrader.DAL.HoseAdapter.Config;
using System.Threading;

namespace StockTrader.DAL.HoseAdapter.MarketInfo
{
    public partial class frmMain : Form
    {
        private AsyncDataProcessor processor;
        private System.Timers.Timer pollTimer = new System.Timers.Timer();
        private System.Timers.Timer trackerTimer = new System.Timers.Timer();
        private bool _isTodayBackupSuccess = false;
        private bool _isRecoverSuccess = false;
        private bool isWorking = false;
        private MarketState _market = MarketState.EndOfDay;

        public frmMain()
        {
            InitializeComponent();
        }

        private void Main_Load(object sender, EventArgs e)
        {
            File_Refresh(Directory.GetCurrentDirectory(), "map");
            UpdateUI();
        }

        private void Main_Resize(object sender, EventArgs e)
        {
            if (FormWindowState.Minimized == WindowState)
                Hide();
        }

        private void trackerTimer_Elapse(object sender, System.Timers.ElapsedEventArgs e)
        {
        }

        private void pollTimer_Elapse(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                if (TransSchedule.IsTradingDate())
                {
                    switch (_market)
                    {
                        case MarketState.BeginOfDay:
                            BeginOfDay();
                            break;
                        case MarketState.Session1:
                            PRSAsyncUpdater(1);
                            break;
                        case MarketState.Session2:
                            PRSAsyncUpdater(2);
                            break;
                        case MarketState.Session3:
                            PRSAsyncUpdater(3);
                            break;
                        case MarketState.Neogtiate:
                            PRSAsyncUpdater(4);
                            break;
                        case MarketState.EndOfDay:
                            if (DateTime.Now.Hour < 12)
                                Backup();
                            EndOfDay();
                            break;
                    }
                }

            }
            catch (Exception ex)
            {
                return;
                throw ex;
            }
            finally
            {
                UpdateUI();
            }
        }

        private void UpdateUI()
        {
            try
            {
                File_UpdatePaths();

                MethodInvoker updateButtonState = delegate
                {
                    btnRecovery.Enabled = !_isRecoverSuccess;
                    btnBackup.Enabled = !_isTodayBackupSuccess;
                };
                if (btnBackup.InvokeRequired || btnRecovery.InvokeRequired)
                {
                    btnBackup.Invoke(updateButtonState);
                    btnRecovery.Invoke(updateButtonState);
                }
                else
                    updateButtonState();

                #region MarketState
                MethodInvoker updateUIState = delegate
                {
                    lblSystemDate.Text = DateTime.Now.ToString("dd/MM/yyyy");
                    lblSystemTime.Text = DateTime.Now.ToString("HH:mm:ss");
                };
                if (lblSystemDate.InvokeRequired || lblSystemTime.InvokeRequired)
                {
                    lblSystemDate.Invoke(updateUIState);
                    lblSystemTime.Invoke(updateUIState);
                }
                else
                    updateUIState();

                string transdate = TransSchedule.getTransDate().ToString("dd/MM/yyyy");
                MethodInvoker updateMarketUIState = delegate
                {
                    lblMarketDate.Text = transdate;
                    _market = TransSchedule.getMarketState();
                    switch (_market)
                    {
                        case MarketState.BeginOfDay:
                            lblMarketStatus.Text = "Begin of day";
                            break;
                        case MarketState.Session1:
                            lblMarketStatus.Text = "Session 1";
                            break;
                        case MarketState.Session2:
                            lblMarketStatus.Text = "Session 2";
                            break;
                        case MarketState.Session3:
                            lblMarketStatus.Text = "Session 3";
                            break;
                        case MarketState.Neogtiate:
                            lblMarketStatus.Text = "Neogtiate";
                            break;
                        default:
                            lblMarketStatus.Text = "Closed";
                            break;
                    }
                    lblMarketStatus.BackColor = Color.PaleGreen;
                };
                if (lblMarketDate.InvokeRequired || lblMarketStatus.InvokeRequired)
                {
                    lblMarketDate.Invoke(updateMarketUIState);
                    lblMarketStatus.Invoke(updateMarketUIState);
                }
                else
                    updateMarketUIState();

                #endregion
            }
            catch (System.Exception e)
            {
                MethodInvoker updateUIState = delegate
                {
                    lblMarketStatus.Text = "ERROR";
                    lblMarketStatus.BackColor = Color.Red;
                };
                if (lblMarketStatus.InvokeRequired)
                {
                    lblMarketStatus.Invoke(updateUIState);
                }
                else
                    updateUIState(); ;
            }
        }

        private void AsyncUpdater(int marketstat)
        {
            try
            {
                string strXML = AppDomain.CurrentDomain.BaseDirectory.Replace("bin\\Debug\\", "") + "Config\\FileDir.xml";
                XmlTextReader rdr = new XmlTextReader(strXML);
                while (rdr.Read())
                {
                    if (string.Compare(rdr.Name, "FileConfig") == 0)
                    {
                        switch (getClassNameByClientID(rdr.ReadSubtree()))
                        {
                             #region Update CTCI_SUBDIR
//                             case "OrderCancellation":
//                                 processor = new AsyncDataProcessor(lblOrderCancellation, typeof(OrderCancellation), 0);
//                                 processor.Execute();
//                                 break;
//                             case "OrderChange":
//                                 processor = new AsyncDataProcessor(lblOrderChange, typeof(OrderChange), 0);
//                                 processor.Execute();
//                                 break;
//                             case "Advertisment":
//                                 processor = new AsyncDataProcessor(lblAdvertisment, typeof(Advertisment), 0);
//                                 processor.Execute();
//                                 break;
//                             case "OFPTDeal":
//                                 processor = new AsyncDataProcessor(lblOFPTDeal, typeof(OFPTDeal), 0);
//                                 processor.Execute();
//                                 break;
//                             case "TFPTDeal":
//                                 processor = new AsyncDataProcessor(lblTFPTDeal, typeof(TFPTDeal), 0);
//                                 processor.Execute();
//                                 break;
//                             case "NewConditionedOrder":
//                                 processor = new AsyncDataProcessor(lblNewConditionedOrder, typeof(NewConditionedOrder), 0);
//                                 processor.Execute();
//                                 break;
//                             case "OrderConfirmation":
//                                 processor = new AsyncDataProcessor(lblOrderConfirmation, typeof(OrderConfirmation), 0);
//                                 processor.Execute();
//                                 break;
//                             case "ConfirmOrderCancel":
//                                 processor = new AsyncDataProcessor(lblConfirmOrderCancel, typeof(ConfirmOrderCancel), 0);
//                                 processor.Execute();
//                                 break;
//                             case "ConfirmOrderChange":
//                                 processor = new AsyncDataProcessor(lblConfirmOrderChange, typeof(ConfirmOrderChange), 0);
//                                 processor.Execute();
//                                 break;
//                             case "DealConfirmation":
//                                 processor = new AsyncDataProcessor(lblDealConfirmation, typeof(DealConfirmation), 0);
//                                 processor.Execute();
//                                 break;
//                             case "PutThroughACK":
//                                 processor = new AsyncDataProcessor(lblPutThroughACK, typeof(PutThroughACK), 0);
//                                 processor.Execute();
//                                 break;
//                             case "Reject":
//                                 processor = new AsyncDataProcessor(lblReject, typeof(Reject), 0);
//                                 processor.Execute();
//                                 break;
//                             case "CrossingDealConfirm":
//                                 processor = new AsyncDataProcessor(lblCorssDealConfirm, typeof(CrossingDealConfirm), 0);
//                                 processor.Execute();
//                                 break;
//                             case "PutThroughDealConfirmation":
//                                 processor = new AsyncDataProcessor(lblPutThroughDealConfirmation, typeof(PutThroughDealConfirmation), 0);
//                                 processor.Execute();
//                                 break;
//                             case "PutThroughDealReply":
//                                 processor = new AsyncDataProcessor(lblPutThroughDealReply, typeof(PutThroughDealReply), 0);
//                                 processor.Execute();
//                                 break;
//                             case "DealCancelRequest":
//                                 processor = new AsyncDataProcessor(lblDealCancelRequest, typeof(DealCancelRequest), 0);
//                                 processor.Execute();
//                                 break;
//                             case "DealCancelReply":
//                                 processor = new AsyncDataProcessor(lblDealCancelReply, typeof(DealCancelReply), 0);
//                                 processor.Execute();
//                                 break;
                             #endregion

                            #region Updpate PRS_DIR
                            case "Securities":
                                processor = new AsyncDataProcessor(lblSecurities, typeof(Securities), marketstat);
                                processor.Execute();
                                break;
                            case "MarketStat":
                                processor = new AsyncDataProcessor(lblMarketStat, typeof(MarketStat), 0);
                                processor.Execute();
                                break;
                            case "TotalMkt":
                                processor = new AsyncDataProcessor(lblTotalMkt, typeof(TotalMkt), 0);
                                processor.Execute();
                                break;
                            case "PutAd":
                                processor = new AsyncDataProcessor(lblPutAd, typeof(PutAd), 0);
                                processor.Execute();
                                break;
                            case "PutExec":
                                processor = new AsyncDataProcessor(lblPutExec, typeof(PutExec), 0);
                                processor.Execute();
                                break;
                            case "PutDc":
                                processor = new AsyncDataProcessor(lblPutDc, typeof(PutDc), 0);
                                processor.Execute();
                                break;
                            case "Le":
                                //                                 processor = new AsyncDataProcessor(lblLe, typeof(Le), 0);
                                //                                 processor.Execute();
                                break;
                            case "NewList":
                                processor = new AsyncDataProcessor(lblNewList, typeof(NewList), 0);
                                processor.Execute();
                                break;
                            case "DeList":
                                processor = new AsyncDataProcessor(lblDeList, typeof(DeList), 0);
                                processor.Execute();
                                break;
                            case "Froom":
                                processor = new AsyncDataProcessor(lblFroom, typeof(Froom), 0);
                                processor.Execute();
                                break;
                            #endregion
                        }
                    }
                }
                rdr.Close();
            }
            catch
            {
                return;
            }
        }

        private void PRSAsyncUpdater(int marketstat)
        {
            try
            {
                string strXML = AppDomain.CurrentDomain.BaseDirectory.Replace("bin\\Debug\\", "") + "Config\\FileDir.xml";
                XmlTextReader rdr = new XmlTextReader(strXML);
                while (rdr.Read())
                {
                    if (string.Compare(rdr.Name, "FileConfig") == 0)
                    {
                        switch (getClassNameByClientID(rdr.ReadSubtree()))
                        {
                            #region Updpate PRS_DIR
                            case "Securities":
                                processor = new AsyncDataProcessor(lblSecurities, typeof(Securities), marketstat);
                                processor.Execute();
                                break;
                            case "MarketStat":
                                processor = new AsyncDataProcessor(lblMarketStat, typeof(MarketStat), 0);
                                processor.Execute();
                                break;
                            case "TotalMkt":
                                processor = new AsyncDataProcessor(lblTotalMkt, typeof(TotalMkt), 0);
                                processor.Execute();
                                break;
                            case "PutAd":
                                processor = new AsyncDataProcessor(lblPutAd, typeof(PutAd), 0);
                                processor.Execute();
                                break;
                            case "PutExec":
                                processor = new AsyncDataProcessor(lblPutExec, typeof(PutExec), 0);
                                processor.Execute();
                                break;
                            case "PutDc":
                                processor = new AsyncDataProcessor(lblPutDc, typeof(PutDc), 0);
                                processor.Execute();
                                break;
                            case "Le":
                                processor = new AsyncDataProcessor(lblLe, typeof(Le), 0);
                                processor.Execute();
                                break;
                            case "NewList":
                                processor = new AsyncDataProcessor(lblNewList, typeof(NewList), 0);
                                processor.Execute();
                                break;
                            case "DeList":
                                processor = new AsyncDataProcessor(lblDeList, typeof(DeList), 0);
                                processor.Execute();
                                break;
                            case "Froom":
                                processor = new AsyncDataProcessor(lblFroom, typeof(Froom), 0);
                                processor.Execute();
                                break;
                            #endregion
                        }
                    }
                }
                rdr.Close();
            }
            catch
            {
                return;
            }
        }

        private void BeginOfDay()
        {
            try
            {
                _isRecoverSuccess = false;
                _isTodayBackupSuccess = false;
                File_Refresh(Directory.GetCurrentDirectory(), "map");
                File_Refresh(Directory.GetCurrentDirectory(), "irs");

                UpdateUI();

                Adapter dac = new Adapter();
                dac.DeleteHoseOrders();
                PRSAsyncUpdater(0);

                pollTimer.Interval = Settings.READ_INTERVAL;
            }
            catch (System.Exception e)
            {
                return;
            }
        }

        private void Backup()
        {
            try
            {
                if (!_isTodayBackupSuccess)
                {
                    Adapter dac = new Adapter();
                    dac.BackupHoseOrders();
                    _isTodayBackupSuccess = true;
                }
            }
            catch (Exception ex)
            {
                _isTodayBackupSuccess = false;
                btnBackup.Enabled = true;
                MessageBox.Show("Backup fail. " + ex.Message, "Error",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void EndOfDay()
        {
            try
            {
                File_Refresh(Directory.GetCurrentDirectory(), "irs");
                pollTimer.Interval = Settings.READ_INTERVAL_HIBERNATE;
            }
            catch (System.Exception e)
            {
                return;
            }
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            if (!isWorking)
            {
                btnStart.Text = "Stop";
                isWorking = true;
                BeginOfDay();

                pollTimer.Enabled = true;
                pollTimer.Interval = Settings.READ_INTERVAL;
                pollTimer.Elapsed += new System.Timers.ElapsedEventHandler(pollTimer_Elapse);

                trackerTimer.Enabled = true;
                trackerTimer.Interval = 1000;
                trackerTimer.Elapsed += new System.Timers.ElapsedEventHandler(trackerTimer_Elapse);
            }
            else
            {
                pollTimer.Enabled = false;
                isWorking = false;
                btnStart.Text = "Start";
            }
        }

        private void btnLogTracer_Click(object sender, EventArgs e)
        {
            Backup();
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            notifyIcon1.Dispose();
            Environment.Exit(1);
        }

        private void btnRecovery_Click(object sender, EventArgs e)
        {
            try
            {
                if ((MessageBox.Show("Data will be CLEAR and REINSERT. Are you sure?", "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes))
                {
                    if (!_isRecoverSuccess)
                    {
                        Adapter dac = new Adapter();
                        dac.DeleteHoseOrders();
                        PRSAsyncUpdater(0);
                        _isRecoverSuccess = true;
                        _isTodayBackupSuccess = false;
                    }
                    else
                        _isRecoverSuccess = false;
                }
            }
            catch (System.Exception ex)
            {
                _isRecoverSuccess = false;
            }

        }

        private void File_UpdatePaths()
        {
            try
            {
                string srcFile = ConfigurationManager.AppSettings["ROOT_PRS"] + "datapath.map";
                string desFile = "datapath.map";
                if (File.Exists(desFile))
                    File.Delete(desFile);
                if (File.Exists(srcFile))
                    CommonLib.SafeCopy(srcFile, desFile);
            }
            catch (System.Exception e)
            {
                return;
            }

        }

        private void File_Refresh(string folder, string extention)
        {
            try
            {
                string[] fileList = Directory.GetFiles(folder, "*." + extention);
                foreach (string udtFile in fileList)
                    File.Delete(udtFile);
            }
            catch
            {
                return;
            }
        }

        private void Main_FormClosed(object sender, FormClosedEventArgs e)
        {
            notifyIcon1.Dispose();
        }
        private string getClassNameByClientID(XmlReader rdr)
        {
            string className = "";
            while (rdr.Read())
                if (rdr.Name == "ClassName")
                    className = rdr.ReadElementContentAsString();
            return className;
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            Show();
            WindowState = FormWindowState.Normal;
        }

    }
}
